// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//

#pragma once

#include <deque>
#include <cantor/proto/common.pb.h>
#include <string>
#include <turbo/strings/string_builder.h>


namespace cantor::common {
    struct LogLocation {
        LogLocation(const char *f, int l, const char *func)
            : file(short_filename(f, 2)),
              line(l),
              function(func) {
        }

        const std::string file;
        const int line{0};
        const std::string function;

        static std::string short_filename(std::string_view file, int depth);
    };

#define LOG_LOCATION LogLocation(__FILE__, __LINE__, __FUNCTION__)

    class IRLogger {
    public:
        void log(LogLocation &&loc, pb::LogLevel level, pb::LogPhase phase, std::string &&pass, std::string &&msg);

        void log_debug(LogLocation &&loc, pb::LogPhase phase, std::string &&pass, std::string &&msg) {
            log(std::move(loc), pb::LogLevel::LOG_DEBUG, phase, std::move(pass), std::move(msg));
        }

        void log_warn(LogLocation &&loc, pb::LogPhase phase, std::string &&pass, std::string &&msg) {
            log(std::move(loc), pb::LogLevel::LOG_WARN, phase, std::move(pass), std::move(msg));
        }

        void log_error(LogLocation &&loc, pb::LogPhase phase, std::string &&pass, std::string &&msg) {
            log(std::move(loc), pb::LogLevel::LOG_ERROR, phase, std::move(pass), std::move(msg));
        }

        template<typename... Args>
        void log(LogLocation &&loc, pb::LogLevel level, pb::LogPhase phase, std::string &&pass, const Args &... args) {
            log(std::move(loc), level, phase, std::move(pass), std::move(turbo::StringBuilder::create(args...)));
        }

        const std::deque<pb::LogMessage> &logs() {
            return logs_;
        }

    private:
        std::deque<pb::LogMessage> logs_;
    };
} // namespace cantor::common
